<template>
  <div class="process-editor">
    <div class="toolbar">
      <el-button-group>
        <el-button @click="handleSave" type="primary">保存</el-button>
        <el-button @click="handleUndo" :disabled="!canUndo">撤销</el-button>
        <el-button @click="handleRedo" :disabled="!canRedo">重做</el-button>
      </el-button-group>
      <el-divider direction="vertical" />
      <el-button-group>
        <el-button @click="handleZoomIn">放大</el-button>
        <el-button @click="handleZoomOut">缩小</el-button>
        <el-button @click="handleResetZoom">重置</el-button>
      </el-button-group>
    </div>

    <div class="editor-container">
      <div class="node-panel">
        <div class="panel-title">节点类型</div>
        <div
          v-for="(label, type) in NODE_LABELS"
          :key="type"
          class="node-item"
          draggable="true"
          @dragstart="handleDragStart($event, type)"
        >
          {{ label }}
        </div>
      </div>

      <div class="graph-container" ref="container"></div>

      <NodeProperties
        :selected-node="selectedNode"
        :on-property-change="handlePropertyChange"
      />

      <VersionPanel
        :process-id="processId"
        :current-version-id="currentVersionId"
        :on-version-switch="handleVersionSwitch"
        :on-version-save="handleVersionSave"
      />
    </div>

    <!-- 保存流程对话框 -->
    <el-dialog
      v-model="dialogVisible"
      title="保存流程"
      width="500px"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="80px"
      >
        <el-form-item label="名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入流程名称"/>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input 
            v-model="form.description" 
            type="textarea" 
            :rows="3"
            placeholder="请输入流程描述"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmSave" :loading="saveLoading">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import LogicFlow from '@logicflow/core'
import { DndPanel, Control, MiniMap } from '@logicflow/extension'
import { registerNodes } from '../components/process/CustomNodes'
import { NODE_TYPES, NODE_LABELS, NODE_CONFIGS } from '../components/process/NodeTypes'
import NodeProperties from '../components/process/NodeProperties.vue'
import VersionPanel from '../components/process/VersionPanel.vue'
import { ElMessage } from 'element-plus'
import { getProcessDetail, createProcess, updateProcess } from '@/api/process'

const route = useRoute()
const router = useRouter()
const processId = route.params.id

const container = ref(null)
const lf = ref(null)
const selectedNode = ref(null)
const canUndo = ref(false)
const canRedo = ref(false)
const currentVersionId = ref(null)

// 保存对话框相关
const dialogVisible = ref(false)
const saveLoading = ref(false)
const formRef = ref(null)
const form = ref({
  name: '',
  description: ''
})
const rules = {
  name: [
    { required: true, message: '请输入流程名称', trigger: 'blur' },
    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  ]
}

// 添加统一的错误处理函数
const handleApiError = async (response) => {
  if (response.status === 401) {
    // token 过期或无效，提示用户刷新页面
    ElMessage.error('登录已过期，请刷新页面重新登录')
    return true
  }
  return false
}

// 初始化LogicFlow
const initLogicFlow = () => {
  if (!container.value) {
    console.error('Container not found')
    return
  }

  try {
    lf.value = new LogicFlow({
      container: container.value,
      grid: true,
      plugins: [DndPanel, Control, MiniMap],
      nodeTextEdit: false,
      edgeTextEdit: false,
      nodeStateStyles: {
        hover: {
          stroke: '#409EFF',
          strokeWidth: 2,
        },
        selected: {
          stroke: '#409EFF',
          strokeWidth: 2,
        },
      },
      edgeStateStyles: {
        hover: {
          stroke: '#409EFF',
          strokeWidth: 2,
        },
        selected: {
          stroke: '#409EFF',
          strokeWidth: 2,
        },
      },
      defaultConfig: {
        circle: {
          r: 25,
        },
        rect: {
          width: 120,
          height: 60,
        },
        diamond: {
          rx: 50,
          ry: 35,
        },
      },
    })

    // 注册自定义节点
    registerNodes(lf.value)

    // 监听事件
    lf.value.on('history:change', ({ undoAble, redoAble }) => {
      canUndo.value = undoAble
      canRedo.value = redoAble
    })

    lf.value.on('node:click', ({ data }) => {
      selectedNode.value = data
    })

    lf.value.on('blank:click', () => {
      selectedNode.value = null
    })

    // 初始化
    lf.value.render()
  } catch (error) {
    console.error('初始化LogicFlow失败:', error)
    ElMessage.error('初始化流程图失败')
  }
}

// 加载流程数据
const loadProcessData = async () => {
  try {
    if (!processId) {
      console.log('新建流程')
      // 新建流程，初始化空画布
      if (lf.value) {
        lf.value.render({
          nodes: [],
          edges: []
        })
      }
      return
    }
    
    console.log('加载流程', processId)
    
    // 使用API层获取流程数据
    const process = await getProcessDetail(processId)
    console.log('流程数据', process)
    
    // 更新表单
    form.value.name = process.name || '未命名流程'
    form.value.description = process.description || ''
    
    // 如果有LogicFlow实例和流程数据，渲染流程图
    if (lf.value && process.flow_data) {
      lf.value.render(process.flow_data)
    }
    
  } catch (error) {
    console.error('加载流程失败:', error)
    ElMessage.error('加载流程失败: ' + (error.message || '未知错误'))
  }
}

// 节点属性变更
const handlePropertyChange = (nodeId, propertyName, value) => {
  if (!lf.value) return
  // 根据节点ID更新节点属性
  const node = lf.value.getNodeModelById(nodeId)
  if (node) {
    node.updateProperties({
      ...node.properties,
      [propertyName]: value
    })
  }
}

// 修改handleSave方法
const handleSave = () => {
  // 如果是新建流程或者需要修改名称，显示对话框
  if (!processId) {
    dialogVisible.value = true
  } else {
    // 如果是编辑现有流程，直接保存
    saveProcess()
  }
}

// 确认保存
const confirmSave = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    dialogVisible.value = false
    saveProcess(form.value)
  } catch (error) {
    console.error('表单验证失败', error)
  }
}

// 保存流程到后端
const saveProcess = async (formData = null) => {
  try {
    saveLoading.value = true
    
    // 获取流程图数据
    let flowData = { nodes: [], edges: [] }
    if (lf.value) {
      flowData = lf.value.getGraphData()
    }
    
    // 准备请求数据
    const processData = {
      name: formData?.name || form.value.name || '未命名流程',
      description: formData?.description || form.value.description || '',
      flow_data: flowData
    }
    
    let result
    if (processId) {
      // 更新已有流程
      result = await updateProcess(processId, processData)
    } else {
      // 创建新流程
      result = await createProcess(processData)
    }
    
    ElMessage.success('保存成功')
    
    // 如果是新创建的流程，跳转到编辑页面
    if (!processId && result.id) {
      router.push(`/process/editor/${result.id}`)
    }
    
  } catch (error) {
    console.error('保存流程失败:', error)
    ElMessage.error('保存失败: ' + (error.message || '未知错误'))
  } finally {
    saveLoading.value = false
  }
}

// 撤销
const handleUndo = () => {
  if (!lf.value) return
  lf.value.undo()
}

// 重做
const handleRedo = () => {
  if (!lf.value) return
  lf.value.redo()
}

// 拖拽开始
const handleDragStart = (event, type) => {
  if (!lf.value) {
    console.error('LogicFlow not initialized')
    return
  }
  
  try {
    lf.value.dnd.startDrag({
      type,
      text: NODE_LABELS[type]
    })
  } catch (error) {
    console.error('拖拽开始失败:', error)
    ElMessage.error('拖拽节点失败')
  }
}

// 放大画布
const handleZoomIn = () => {
  if (!lf.value) return
  lf.value.zoom(true)
}

// 缩小画布
const handleZoomOut = () => {
  if (!lf.value) return
  lf.value.zoom(false)
}

// 重置缩放
const handleResetZoom = () => {
  if (!lf.value) return
  lf.value.resetZoom()
}

// 处理版本切换
const handleVersionSwitch = (versionId) => {
  currentVersionId.value = versionId
  // 加载该版本的流程数据
  console.log('切换到版本', versionId)
}

// 保存版本
const handleVersionSave = (comment) => {
  console.log('保存版本', comment)
  // 保存当前流程为新版本
}

onMounted(async () => {
  try {
    await nextTick()
    // 初始化 LogicFlow
    initLogicFlow()
    
    // 加载流程数据
    await loadProcessData()
  } catch (error) {
    console.error('组件挂载失败:', error)
    ElMessage.error('初始化失败')
  }
})
</script>

<style lang="scss" scoped>
.process-editor {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.toolbar {
  padding: 8px;
  border-bottom: 1px solid #dcdfe6;
  background-color: #fff;
}

.editor-container {
  flex: 1;
  display: flex;
  position: relative;
  overflow: hidden;
}

.node-panel {
  width: 200px;
  padding: 16px;
  border-right: 1px solid #dcdfe6;
  background-color: #fff;
}

.panel-title {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 16px;
}

.node-item {
  padding: 8px;
  margin-bottom: 8px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  cursor: move;
  background-color: #f5f7fa;
}

.node-item:hover {
  background-color: #ecf5ff;
}

.graph-container {
  flex: 1;
  background-color: #f5f7fa;
}

:deep(.lf-control) {
  position: absolute;
  right: 20px;
  top: 20px;
}

:deep(.lf-mini-map) {
  position: absolute;
  right: 20px;
  bottom: 20px;
  background-color: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
</style> 